#ifndef _ICM20602_H
#define _ICM20602_H

#include "main.h"

/**
 * ICM20602的SPI操作有如下特征：
 * 1. 数据以高字节(MSB)在前，低字节(LSB)在后
 * 2. 数据在SCK上升沿时锁存，在下降沿时读取
 * 3. SCK最高频率为10MHz
 * 4. SPI读写操作需要16个以上时钟周期，即两字节以上，第一个字节为寄存器地址，其中第一位是读/写位，其余字节为传输的数据。
 */

/**
 * @brief SPI通信相关宏定义
 */
#define ICM20602_SPI_CHANNEL		SPI2

#define ICM20602_SPI_SCLK_PIN		LL_GPIO_PIN_13
#define ICM20602_SPI_SCLK_PORT		GPIOB
#define ICM20602_SPI_SCLK_CLK		LL_AHB1_GRP1_PERIPH_GPIOB

#define ICM20602_SPI_MISO_PIN		LL_GPIO_PIN_14
#define ICM20602_SPI_MISO_PORT		GPIOB
#define ICM20602_SPI_MISO_CLK		LL_AHB1_GRP1_PERIPH_GPIOB

#define ICM20602_SPI_MOSI_PIN		LL_GPIO_PIN_15
#define ICM20602_SPI_MOSI_PORT		GPIOB
#define ICM20602_SPI_MOSI_CLK		LL_AHB1_GRP1_PERIPH_GPIOB

#define ICM20602_SPI_CS_PIN			LL_GPIO_PIN_11
#define ICM20602_SPI_CS_PORT		GPIOB
#define ICM20602_SPI_CS_CLK			LL_AHB1_GRP1_PERIPH_GPIOB

#define ICM20602_INT_PIN			LL_GPIO_PIN_12
#define ICM20602_INT_PORT			GPIOB
#define ICM20602_INT_CLK			LL_AHB1_GRP1_PERIPH_GPIOB


/**
 * @brief 片选操作，低电平有效
 */
#define CHIP_SELECT(ICM20602)		LL_GPIO_ResetOutputPin(ICM20602_SPI_CS_PORT, ICM20602_SPI_CS_PIN)
#define CHIP_DESELECT(ICM20602)		LL_GPIO_SetOutputPin(ICM20602_SPI_CS_PORT, ICM20602_SPI_CS_PIN)

/**
 * @brief ICM20602寄存器地址
 */

#define	XG_OFFS_TC_H	0x04
#define	XG_OFFS_TC_L	0x05
#define	YG_OFFS_TC_H	0x07
#define	YG_OFFS_TC_L	0x08
#define	ZG_OFFS_TC_H	0x0A
#define	ZG_OFFS_TC_L	0x0B
#define	SELF_TEST_X_ACCEL	0x0D
#define	SELF_TEST_Y_ACCEL	0x0E
#define	SELF_TEST_Z_ACCEL	0x0F
#define	XG_OFFS_USRH	0x13
#define	XG_OFFS_USRL	0x14
#define	YG_OFFS_USRH	0x15
#define	YG_OFFS_USRL	0x16
#define	ZG_OFFS_USRH	0x17
#define	ZG_OFFS_USRL	0x18
#define	SMPLRT_DIV	0x19
#define	CONFIG	0x1A    //The default value of the register is 0x80.
#define	GYRO_CONFIG	0x1B
#define	ACCEL_CONFIG	0x1C
#define	ACCEL_CONFIG2	0x1D
#define	LP_MODE_CFG	0x1E
#define	ACCEL_WOM_X_THR	0x20
#define	ACCEL_WOM_Y_THR	0x21
#define	ACCEL_WOM_Z_THR	0x22
#define	FIFO_EN	0x23
#define	FSYNC_INT	0x36
#define	INT_PIN_CFG	0x37
#define	INT_ENABLE	0x38
#define	FIFO_WM_INT_STATUS	0x39
		
#define	INT_STATUS	0x3A
#define	ACCEL_XOUT_H	0x3B
#define	ACCEL_XOUT_L	0x3C
#define	ACCEL_YOUT_H	0x3D
#define	ACCEL_YOUT_L	0x3E
#define	ACCEL_ZOUT_H	0x3F
#define	ACCEL_ZOUT_L	0x40
#define	TEMP_OUT_H	0x41
#define	TEMP_OUT_L	0x42
#define	GYRO_XOUT_H	0x43
#define	GYRO_XOUT_L	0x44
#define	GYRO_YOUT_H	0x45
#define	GYRO_YOUT_L	0x46
#define	GYRO_ZOUT_H	0x47
#define	GYRO_ZOUT_L	0x48
#define	SELF_TEST_X_GYRO	0x50
#define	SELF_TEST_Y_GYRO	0x51
#define	SELF_TEST_Z_GYRO	0x52
#define	FIFO_WM_TH1	0x60
#define	FIFO_WM_TH2	0x61
#define	SIGNAL_PATH_RESET	0x68
#define	ACCEL_INTEL_CTRL	0x69
#define	USER_CTRL	0x6A
#define	PWR_MGMT_1	0x6B //The default value of the register is 0x41.
#define	PWR_MGMT_2	0x6C
#define	I2C_IF	0x70
#define	FIFO_COUNTH	0x72
#define	FIFO_COUNTL	0x73
#define	FIFO_R_W	0x74
#define	WHO_AM_I	0x75 //The default value of the register is 0x12.
#define	XA_OFFSET_H	0x77
#define	XA_OFFSET_L	0x78
#define	YA_OFFSET_H	0x7A
#define	YA_OFFSET_L	0x7B
#define	ZA_OFFSET_H	0x7D
#define	ZA_OFFSET_L	0x7E

/**
 * @brief 结构体声明
 */
typedef struct{
	short gyro_raw[3];
	short accel_raw[3];
	
	float gyro_dps[3];	// deg/s
	float gyro_rps[3];	// rad/s
	float accel_mps[3];	// m/s
	
	float rol;
	float pit;
	float yaw;
	
}sensor_st;
extern sensor_st sensor;

extern int imu_data_ready;


/**
 * @brief 全局函数声明
 */
int ICM20602_Initialization(void);
void ICM20602_Get6AxisRawData(short *accel, short *gyro);

#endif